
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fcntl.h>
#include <unistd.h>

#include <libplatereport.h>
#include <liblinkclient.h>
#include <libsqlite.h>
#include <librecord.h>

struct handle_test
{
	char connect_addr[32];
	unsigned short connect_port;

	char server_addr[32];
	unsigned short server_port;

	unsigned int magic;
};

int main(int argc, char **argv)
{
	int oc = 0;

	char ifname[32] = {0};
	unsigned short port = 0;

	Lib_PlateReport *report = NULL;
	Lib_LinkClient *linkclient = NULL;
	Lib_Sqlite *sqlite = NULL;
	Lib_Record *record = NULL;

	unsigned int magic = 0;
	unsigned int type = 0;

	unsigned int test_magic = 0;

	char buffer[2048] = {0};
	int size = 0;

	if(1 == argc)
	{
		printf("-i\t-> interface\n-p\t-> port\n");
	}

	while(0 < (oc = getopt(argc, argv, "i:p:")))
	{
		switch(oc)
		{
			case 'i':
				strncpy(ifname, optarg, sizeof(ifname));
				break;
			case 'p':
				port = (unsigned short)strtoul(optarg, NULL, 0);
				break;
			case '?':
				goto out;
				break;
			case ':':
				goto out;
				break;
		}
	}

	if(0 > strlen(ifname) || 0 == port)
	{
		goto out;
	}

	report = Lib_PlateReport::getObject(ifname, port);

	if(NULL == report)
	{
		goto out;
	}

	linkclient = Lib_LinkClient::getObject(ifname, port + 1);

	if(NULL == linkclient)
	{
		goto out;
	}

	sqlite = Lib_Sqlite::getObject("./config.db");

	if(NULL == sqlite)
	{
		goto out;
	}

	record = Lib_Record::getObject(sqlite);

	if(NULL == record)
	{
		goto out;
	}

	while(1)
	{

		memset(buffer, 0, sizeof(buffer));
		size = sizeof(buffer);

		if(true == report->recv_data(&magic, &type, buffer, &size))
		{
			printf("report type = %d\n", type);

			switch(type)
			{
				case 0x0:
					{
						test_magic = magic;
						snprintf(buffer, sizeof(buffer), "%08X", magic);
						printf("new client: %s\n", buffer);
						if(true == record->insert(buffer))
						{
							report->send_data_s(magic, type, buffer, strlen(buffer));
						}
						else
						{
							report->send_data_s(magic, type, NULL, 0);
						}
					}
					break;
				case 0x1:
					{
						printf("%s\n", buffer);
						linkclient->send_data(magic, 0, buffer, size);
					}
					break;
				case 0x10:
					{
						struct handle_test *test = (struct handle_test *)buffer;
						printf("link %08X <=> %08X\n", test->magic, magic);
						linkclient->link(test->magic, magic);
					}
					break;
				default:
					break;
			}
		}

		memset(buffer, 0, sizeof(buffer));
		size = sizeof(buffer);

		if(true == linkclient->recv_data(&magic, &type, buffer, &size))
		{
			switch(type)
			{
				case 0:
					report->send_data_s(magic, type, buffer, size);
					break;
				default:
					{
						struct handle_test test;

						printf("link %08X <=> ????????\n", magic);

						strncpy(test.connect_addr, "192.168.1.106", sizeof(test.connect_addr));
						test.connect_port = 60000;

						strncpy(test.server_addr, report->getLocalAddr(), sizeof(test.connect_addr));
						test.server_port = port;

						test.magic = magic;

						report->send_data_s(test_magic, 0x10, (char *)&test, sizeof(test));
					}
					break;
			}
		}
	}

out:
	return 0;
}
